from pr3da.data.PictureTools import Picture, Pr3daSet
from pr3da.data.OrderedSet import OrderedSet
from direct.interval.LerpInterval import LerpPosInterval
from direct.interval.IntervalGlobal import *

MAX_SET_COUNT=3

class PluginRegistry:
  def __init__(self):
    self._plugins = {}

  def registerPlugin(self, plugin):
    self._plugins[plugin.id] = plugin

  def getPlugins(self):
    return self._plugins.values()

  def search(self, query, plugins=None):
    if plugins is None:
      pl = self.getPlugins()
    else:
      pl = plugins
    results = []
    for p in pl:
      results.append((p, p.search(query)))
    return results


class Pr3daManager():
  def __init__(self):
    self.pluginRegistry = PluginRegistry()
    self.delegations = {
      'registerPlugin': self.pluginRegistry.registerPlugin,
      'getPlugins' : self.pluginRegistry.getPlugins,
      'search' : self.pluginRegistry.search,
    }
    self.pictures = {}
    self.picture_last_set_count = {}
    self.sets = OrderedSet()
    self.set_count = 0
    self.superset_node_path = render.attachNewNode('sets')

  def __getattr__(self, name):
    if name in self.delegations:
      return self.delegations[name]
    else:
      raise AttributeError("%s instance has no attribute '%s'" % (self.__class__, name))

  def createSet(self, purls):
    set = Pr3daSet()
    for purl in purls:
      #print('purl is %s' % str(purl))
      plugin, urls = purl[0], purl[1]
      for url in urls:
        if url in self.pictures:
          picture = self.pictures[url]
        else:
          picture = Picture(url, plugin.getLoader())
        set.addPicture(picture)
        self.pictures[url] = picture
        self.picture_last_set_count[url] = self.set_count
    self.set_count = self.set_count + 1
    
    return set
  
  def _activatePSet(self, pset):
    self.sets.add(pset)
    pset.getNodePath().setPos(0,0,0)
    pset.getNodePath().reparentTo(render)
    pset.getNodePath().wrtReparentTo(self.superset_node_path)

  def _layoutSet(self, pset, toggleGlow=True):
    playout = pset.getLayout()
    playout.prepareLayout(pset)
    pset.activate(True)
    playout.doLayout()
    if toggleGlow:
      pset.toggleGlow()

    #TODO: check if we can center the set somehow

  def addSet(self, pset):
    s = Sequence(name="set transition")
    if len(self.sets) > 0:
      pos = self.superset_node_path.getPos()
      pos.addY(300)
      pos.addX(10)
      pos.addZ(10)
      s.append(Func(self.getActiveSet().toggleGlow))
      s.append(LerpPosInterval(self.superset_node_path, 1.0, pos, blendType = 'easeInOut'))
    s.append(Func(self._activatePSet, pset))
    s.append(Func(self._layoutSet, pset))
    s.start()
    '''
    if len(self.sets) > MAX_SET_COUNT:
      self.sets[0].destroy()
      del(self.sets[0])
    '''

  def reLayout(self):
    s = Sequence(name="set transition")
    pset = self.getActiveSet()
    s.append(Func(self._activatePSet, pset))
    s.append(Func(self._layoutSet, pset, False))
    s.start()

  def getActiveSet(self):
    return self.sets[-1]
      
  def toggleGlow(self):
    l = len(self.sets)
    if l > 0:
      set = self.sets[l-1]
      set.toggleGlow()
      
  def toggleReflect(self):
    l = len(self.sets)
    if l > 0:
      set = self.sets[l-1]
      set.toggleReflect()
